/*
 * @(#)Log.java 1.0 2011/05/10
 */
package stardust.core.log;


import java.lang.Thread.UncaughtExceptionHandler;
import java.util.Date;
import stardust.core.support.conversion.StringConversion;


/**
 * <code>Log</code> 类提供日志记录功能。 注意：暂时只能用于标准输出的日志打印，后续将增加网络、文件甚至数据库级的日志记录。
 * <p/>
 * @see Log.Level
 * @see Log.LogUncaughtExceptionHandler
 * @version 1.0, 2011/05/10
 * @author ChenChang
 */
public class Log
{

  /**
   * 全局公共日志记录器。
   */
  public static final Log global = new Log("global");

  /**
   * 日志记录器名称。
   */
  private String name;

  /**
   * 通过自定义名称构造日志记录器。
   * <p/>
   * @param name
* 自定义的日志记录器名称，它是一个{@link String}对象。
   */
  public Log(String name)
  {
    this.name = name;
  }

  public Log(Class<?> cls)
  {
    this(cls.getName());
  }

  public Log(Object obj)
  {
    this(obj.getClass().getName());
  }

  public String getName()
  {
    return this.name;
  }

  private synchronized void writeLog(Level level, Throwable e, Object... msg)
  {
    StringBuffer buf = new StringBuffer();

    buf.append("<").append(StringConversion.parseDate(new Date(), "yyyy-MM-dd HH:mm:ss")).append(">");
    buf.append("<").append(level).append(">");
    buf.append("<").append(this.name).append(">");

    for (int i = 0; i < msg.length; i++)
    {
      if (i == 0)
      {
        buf.append("\n");
      }

      buf.append(msg[i]);
    }

    if (level == Level.error || level == Level.warning)
    {
      System.out.println(buf);//err

      if (e != null)
      {
        e.printStackTrace(System.out);//err
      }
    }
    else
    {
      System.out.println(buf);

      if (e != null)
      {
        e.printStackTrace(System.out);
      }
    }
  }

  public void error(Throwable e, Object... msg)
  {
    this.writeLog(Level.error, e, msg);
  }

  public void warning(Throwable e, Object... msg)
  {
    this.writeLog(Level.warning, e, msg);
  }

  public void warning(Object... msg)
  {
    this.writeLog(Level.warning, null, msg);
  }

  public void info(Object... msg)
  {
    this.writeLog(Level.info, null, msg);
  }

  public void trace(Object... msg)
  {
    this.writeLog(Level.trace, null, msg);
  }

  public void debug(Object... msg)
  {
    this.writeLog(Level.debug, null, msg);
  }

  static
  {
    LogUncaughtExceptionHandler sueh = new LogUncaughtExceptionHandler();

    Thread.currentThread().setUncaughtExceptionHandler(sueh);
    Thread.setDefaultUncaughtExceptionHandler(sueh);
  }

  public static enum Level
  {

    error("ERROR"),
    warning(" WARN"),
    info(" INFO"),
    trace("TRACE"),
    debug("DEBUG");

    private String value;

    private Level(String value)
    {
      this.value = value;
    }

    public String toString()
    {
      return this.value;
    }

  }

  public static class LogUncaughtExceptionHandler implements UncaughtExceptionHandler
  {

    private Log log = new Log(this);

    public void uncaughtException(Thread t, Throwable e)
    {
      this.log.error(e, "未捕获的异常出现在线程[", t.getName(), "]：");
    }

  }

}
